home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DJLSR106.ARJ / DOSCAN.C < prev    next >
C/C++ Source or Header  |  1992-04-07  |  5KB  |  295 lines

  1. /* This is file DOSCAN.C */
  2. /* This file may have been modified by DJ Delorie (Jan 1991).  If so,
  3. ** these modifications are Coyright (C) 1991 DJ Delorie, 24 Kirsten Ave,
  4. ** Rochester NH, 03867-2954, USA.
  5. */
  6.  
  7. #define _doscan _____doscan
  8. #include <stdio.h>
  9. #include <ctype.h>
  10. #undef _doscan
  11.  
  12. #define    SPC    01
  13. #define    STP    02
  14.  
  15. #define    SHORT    0
  16. #define    REGULAR    1
  17. #define    LONG    2
  18. #define    INT    0
  19. #define    FLOAT    1
  20.  
  21. static char *_getccl();
  22.  
  23. static char _sctab[256] = {
  24.     0,0,0,0,0,0,0,0,
  25.     0,SPC,SPC,0,0,0,0,0,
  26.     0,0,0,0,0,0,0,0,
  27.     0,0,0,0,0,0,0,0,
  28.     SPC,0,0,0,0,0,0,0,
  29.     0,0,0,0,0,0,0,0,
  30.     0,0,0,0,0,0,0,0,
  31.     0,0,0,0,0,0,0,0,
  32. };
  33.  
  34. _doscan(FILE *iop, const char *fmt, void **argp)
  35. {
  36.     register int ch;
  37.     int nmatch, len, ch1;
  38.     int **ptr, fileended, size;
  39.  
  40.     nmatch = 0;
  41.     fileended = 0;
  42.     for (;;) switch (ch = *fmt++) {
  43.     case '\0': 
  44.         return (nmatch);
  45.     case '%': 
  46.         if ((ch = *fmt++) == '%')
  47.             goto def;
  48.         ptr = 0;
  49.         if (ch != '*')
  50.             ptr = argp++;
  51.         else
  52.             ch = *fmt++;
  53.         len = 0;
  54.         size = REGULAR;
  55.         while (isdigit(ch)) {
  56.             len = len*10 + ch - '0';
  57.             ch = *fmt++;
  58.         }
  59.         if (len == 0)
  60.             len = 30000;
  61.         if (ch=='l') {
  62.             size = LONG;
  63.             ch = *fmt++;
  64.         } else if (ch=='h') {
  65.             size = SHORT;
  66.             ch = *fmt++;
  67.         } else if (ch=='[')
  68.             fmt = _getccl(fmt);
  69.         if (isupper(ch)) {
  70.             ch = tolower(ch);
  71.             size = LONG;
  72.         }
  73.         if (ch == '\0')
  74.             return(-1);
  75.         if (_innum(ptr, ch, len, size, iop, &fileended) && ptr)
  76.             nmatch++;
  77.         if (fileended)
  78.             return(nmatch? nmatch: -1);
  79.         break;
  80.  
  81.     case ' ':
  82.     case '\n':
  83.     case '\t': 
  84.         while ((ch1 = getc(iop))==' ' || ch1=='\t' || ch1=='\n')
  85.             ;
  86.         if (ch1 != EOF)
  87.             ungetc(ch1, iop);
  88.         break;
  89.  
  90.     default: 
  91.     def:
  92.         ch1 = getc(iop);
  93.         if (ch1 != ch) {
  94.             if (ch1==EOF)
  95.                 return(-1);
  96.             ungetc(ch1, iop);
  97.             return(nmatch);
  98.         }
  99.     }
  100. }
  101.  
  102. static
  103. _innum(ptr, type, len, size, iop, eofptr)
  104. int **ptr, *eofptr;
  105. FILE *iop;
  106. {
  107.     extern double atof();
  108.     register char *np;
  109.     char numbuf[64];
  110.     register c, base;
  111.     int expseen, scale, negflg, c1, ndigit;
  112.     long lcval;
  113.  
  114.     if (type=='c' || type=='s' || type=='[')
  115.         return(_instr(ptr? *(char **)ptr: (char *)NULL, type, len, iop, eofptr));
  116.     lcval = 0;
  117.     ndigit = 0;
  118.     scale = INT;
  119.     if (type=='e'||type=='f'||type=='g')
  120.         scale = FLOAT;
  121.     base = 10;
  122.     if (type=='o')
  123.         base = 8;
  124.     else if (type=='x')
  125.         base = 16;
  126.     np = numbuf;
  127.     expseen = 0;
  128.     negflg = 0;
  129.     while ((c = getc(iop))==' ' || c=='\t' || c=='\n');
  130.     if (c=='-') {
  131.         negflg++;
  132.         *np++ = c;
  133.         c = getc(iop);
  134.         len--;
  135.     } else if (c=='+') {
  136.         len--;
  137.         c = getc(iop);
  138.     }
  139.     for ( ; --len>=0; *np++ = c, c = getc(iop)) {
  140.         if (isdigit(c)
  141.          || base==16 && ('a'<=c && c<='f' || 'A'<=c && c<='F')) {
  142.             ndigit++;
  143.             if (base==8)
  144.                 lcval <<=3;
  145.             else if (base==10)
  146.                 lcval = ((lcval<<2) + lcval)<<1;
  147.             else
  148.                 lcval <<= 4;
  149.             c1 = c;
  150.             if (isdigit(c))
  151.                 c -= '0';
  152.             else if ('a'<=c && c<='f')
  153.                 c -= 'a'-10;
  154.             else
  155.                 c -= 'A'-10;
  156.             lcval += c;
  157.             c = c1;
  158.             continue;
  159.         } else if (c=='.') {
  160.             if (base!=10 || scale==INT)
  161.                 break;
  162.             ndigit++;
  163.             continue;
  164.         } else if ((c=='e'||c=='E') && expseen==0) {
  165.             if (base!=10 || scale==INT || ndigit==0)
  166.                 break;
  167.             expseen++;
  168.             *np++ = c;
  169.             c = getc(iop);
  170.             if (c!='+'&&c!='-'&&('0'>c||c>'9'))
  171.                 break;
  172.         } else
  173.             break;
  174.     }
  175.     if (negflg)
  176.         lcval = -lcval;
  177.     if (c != EOF) {
  178.         ungetc(c, iop);
  179.         *eofptr = 0;
  180.     } else
  181.         *eofptr = 1;
  182.      if (ptr==NULL || np==numbuf || (negflg && np==numbuf+1) )/* gene dykes*/
  183.         return(0);
  184.     *np++ = 0;
  185.     switch((scale<<4) | size) {
  186.  
  187.     case (FLOAT<<4) | SHORT:
  188.     case (FLOAT<<4) | REGULAR:
  189.         **(float **)ptr = atof(numbuf);
  190.         break;
  191.  
  192.     case (FLOAT<<4) | LONG:
  193.         **(double **)ptr = atof(numbuf);
  194.         break;
  195.  
  196.     case (INT<<4) | SHORT:
  197.         **(short **)ptr = lcval;
  198.         break;
  199.  
  200.     case (INT<<4) | REGULAR:
  201.         **(int **)ptr = lcval;
  202.         break;
  203.  
  204.     case (INT<<4) | LONG:
  205.         **(long **)ptr = lcval;
  206.         break;
  207.     }
  208.     return(1);
  209. }
  210.  
  211. static
  212. _instr(ptr, type, len, iop, eofptr)
  213. register char *ptr;
  214. register FILE *iop;
  215. int *eofptr;
  216. {
  217.     register ch;
  218.     register char *optr;
  219.     int ignstp;
  220.  
  221.     *eofptr = 0;
  222.     optr = ptr;
  223.     if (type=='c' && len==30000)
  224.         len = 1;
  225.     ignstp = 0;
  226.     if (type=='s')
  227.         ignstp = SPC;
  228.     while ((ch = getc(iop)) != EOF && _sctab[ch] & ignstp)
  229.         ;
  230.     ignstp = SPC;
  231.     if (type=='c')
  232.         ignstp = 0;
  233.     else if (type=='[')
  234.         ignstp = STP;
  235.     while (ch!=EOF && (_sctab[ch]&ignstp)==0) {
  236.         if (ptr)
  237.             *ptr++ = ch;
  238.         if (--len <= 0)
  239.             break;
  240.         ch = getc(iop);
  241.     }
  242.     if (ch != EOF) {
  243.         if (len > 0)
  244.             ungetc(ch, iop);
  245.         *eofptr = 0;
  246.     } else
  247.         *eofptr = 1;
  248.     if (ptr && ptr!=optr) {
  249.         if (type!='c')
  250.             *ptr++ = '\0';
  251.         return(1);
  252.     }
  253.     return(0);
  254. }
  255.  
  256. static char *
  257. _getccl(s)
  258. register unsigned char *s;
  259. {
  260.     register c, t;
  261.  
  262.     t = 0;
  263.     if (*s == '^') {
  264.         t++;
  265.         s++;
  266.     }
  267.     for (c = 0; c < (sizeof _sctab / sizeof _sctab[0]); c++)
  268.         if (t)
  269.             _sctab[c] &= ~STP;
  270.         else
  271.             _sctab[c] |= STP;
  272.     if ((c = *s) == ']' || c == '-') {    /* first char is special */
  273.         if (t)
  274.             _sctab[c] |= STP;
  275.         else
  276.             _sctab[c] &= ~STP;
  277.         s++;
  278.     }
  279.     while ((c = *s++) != ']') {
  280.         if (c==0)
  281.             return((char *)--s);
  282.         else if (c == '-' && *s != ']' && s[-2] < *s) {
  283.             for (c = s[-2] + 1; c < *s; c++)
  284.                 if (t)
  285.                     _sctab[c] |= STP;
  286.                 else
  287.                     _sctab[c] &= ~STP;
  288.         } else if (t)
  289.             _sctab[c] |= STP;
  290.         else
  291.             _sctab[c] &= ~STP;
  292.     }
  293.     return((char *)s);
  294. }
  295.